package com.jerkin.dubbo.context;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @version V1.0
 * @ClassName: InitExceptionHandleAnnotaions
 * @Description:
 * @author: huhongzhi
 * @date: 2020/8/3 21:48
 */
@Configuration
public class InitExceptionHandleAnnotaions implements ApplicationContextAware, InitializingBean, DisposableBean {

    private static ApplicationContext applicationContext;

    private static Map<String, ExceptionHandleRo> map = new ConcurrentHashMap<>();

    @Override
    public void destroy() throws Exception {

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (applicationContext != null) {
            String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
            String[] var3 = beanDefinitionNames;
            int var4 = beanDefinitionNames.length;

            for (int var5 = 0; var5 < var4; ++var5) {
                String beanDefinitionName = var3[var5];
                if (!applicationContext.isSingleton(beanDefinitionName)) {
                    continue;
                }
                Object bean = applicationContext.getBean(beanDefinitionName);
                Method[] methods = bean.getClass().getDeclaredMethods();
                Method[] var9 = methods;
                int var10 = methods.length;

                for (int var11 = 0; var11 < var10; ++var11) {
                    Method method = var9[var11];
                    ExceptionHandleTag tag = (ExceptionHandleTag) AnnotationUtils.findAnnotation(method, ExceptionHandleTag.class);
                    if (tag != null) {
                        String key = bean.getClass().getName() + "#" + method.getName();
                        ExceptionHandleRo exceptionHandleRo = initExceptionHandleTag(tag);
                        map.put(key, exceptionHandleRo);
                    }
                }
            }

        }
    }

    private ExceptionHandleRo initExceptionHandleTag(ExceptionHandleTag tag) {
        ExceptionHandleRo exceptionHandleRo = new ExceptionHandleRo();
        exceptionHandleRo.setExceptions(tag.exceptions());
        exceptionHandleRo.setNotify(tag.isNotify());
        exceptionHandleRo.setReferenceMethod(tag.referenceMethod());
        return exceptionHandleRo;
    }

    public static ExceptionHandleRo getExceptionHandle(String key) {
        return map.get(key);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        InitExceptionHandleAnnotaions.applicationContext = applicationContext;
    }
}
